﻿using System;

namespace Simp.Model.CoreExpressions
{
	/// <summary>Compute the quotient of two expressions.</summary>
	[ExpressionName("Division")]
	public class DivisionExpression : BinaryNumericExpressionBase
	{
		/// <summary>Performs division.</summary>
		/// <param name="simplificationMode"></param>
		/// <param name="leftInteger"></param>
		/// <param name="leftRational"></param>
		/// <param name="leftReal"></param>
		/// <param name="rightInteger"></param>
		/// <param name="rightRational"></param>
		/// <param name="rightReal"></param>
		/// <returns></returns>
		protected override IExpression SimplifyNumerics(
			SimplificationMode simplificationMode,
			IntegerExpression leftInteger,
			RationalExpression leftRational,
			RealExpression leftReal,
			IntegerExpression rightInteger,
			RationalExpression rightRational,
			RealExpression rightReal)
		{
			if (leftInteger != null)
			{
				if (rightInteger != null)
				{
					return RationalExpression.GetRational(leftInteger.Value, rightInteger.Value);
				}
				else if (rightRational != null)
				{
					return RationalExpression.GetRational(
						leftInteger.Value * rightRational.Denominator,
						rightRational.Denominator);
				}
			}
			else if (leftRational != null)
			{
				if (rightInteger != null)
				{
					return RationalExpression.GetRational(
						leftRational.Numerator,
						leftRational.Denominator * rightInteger.Value);
				}
				else if (rightRational != null)
				{
					return RationalExpression.GetRational(
						leftRational.Numerator * rightRational.Denominator,
						rightRational.Numerator * leftRational.Denominator);
				}
				else if (rightReal != null && simplificationMode == SimplificationMode.AllowApproximation)
				{
					return new RealExpression(leftRational.Numerator / (leftRational.Denominator * rightReal.Value));
				}
			}
			else if (leftReal != null)
			{
				if (rightRational != null)
				{
					return new RealExpression(leftReal.Value * rightRational.Denominator / (double)rightRational.Numerator);
				}
				else if (rightReal != null)
				{
					return new RealExpression(leftReal.Value / rightReal.Value);
				}
			}

			return null;
		}

		/// <summary>Division isn't commuting.</summary>
		protected override bool IsCommuting
		{
			get { return false; }
		}

		/// <summary>Returns the division symbol.</summary>
		protected override string OperationSymbol
		{
			get { return "/"; }
		}
	}
}